﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;

using G.Runtime;

namespace Conquest
{
    public class Controller : Component
    {
        public delegate void ControllerHandler(Controller controller);
        public event ControllerHandler Step;
        
        enum StateEnum
        {
            Choosing,
            Deploying
        }
        
        private StateEnum _State;
        private LaunchingArea _LaunchingArea;
        private StateMap _StateMap;
        private List<PlayerPad> _PlayOrder = new List<PlayerPad>();
        private int _Step;
        
        public Controller()
        {
            _State = StateEnum.Choosing;
        }
        
        public LaunchingArea LaunchingArea
        {
            get { return _LaunchingArea; }
            set
            {
                _LaunchingArea = value;
                if (_LaunchingArea != null)
                {
                    _LaunchingArea.PlayerPad1.Homeland.StateChanged += OnStateChanged;
                    _LaunchingArea.PlayerPad2.Homeland.StateChanged += OnStateChanged;
                    _LaunchingArea.ProgressBar.Value = 0;
                }
            }
        }
        
        public StateMap StateMap
        {
            get { return _StateMap; }
            set { _StateMap = value; }
        }
        
        private void OnStateChanged(Homeland homland)
        {
            Homeland h1 = _LaunchingArea.PlayerPad1.Homeland;
            Homeland h2 = _LaunchingArea.PlayerPad2.Homeland;
            
            if (h1.State == Homeland.StateEnum.Full &&
                h2.State == Homeland.StateEnum.Full)
            {
                _StateMap.Usable = true;
                _State = StateEnum.Deploying;
                EnablePlayer();
            }
            else if (h1.State == Homeland.StateEnum.Empty &&
                     h2.State == Homeland.StateEnum.Empty)
            {
                _StateMap.Usable = false;
                _State = StateEnum.Choosing;
                _LaunchingArea.PlayerPad1.Enabled = true;
                _LaunchingArea.PlayerPad2.Enabled = true;
                _Step++;
                _LaunchingArea.ProgressBar.Value = _Step;
                
                ScoreComputer c = new ScoreComputer(
                    _StateMap, _LaunchingArea);
                c.AssignScores();
            }
        }
        
        StateEnum State
        {
            get { return _State; }
        }

        private class Comp : IComparer<PlayerPad>
        {
            int IComparer<PlayerPad>.Compare(PlayerPad x, PlayerPad y)
            {
                return y.Homeland.CountMen - x.Homeland.CountMen;
            }
        }
        
        private void EnablePlayer()
        {
            if (_PlayOrder.Count == 0)
            {
                _PlayOrder.Add(_LaunchingArea.PlayerPad1);
                _PlayOrder.Add(_LaunchingArea.PlayerPad2);
                _PlayOrder.Sort(new Comp());
            }
            
            for (int i = 0; i < _PlayOrder.Count; i++)
            {
                PlayerPad pad = _PlayOrder[i];
                
                if (pad.Homeland.CountMen == 0)
                {
                    _PlayOrder.Remove(pad);
                    pad.Enabled = false;
                    i = 0;
                    continue;
                }
            }
            
            for (int i = 0; i < _PlayOrder.Count; i++)
            {
                PlayerPad pad = _PlayOrder[i];
                
                if (i == 0)
                {
                    pad.Enabled = true;
                    pad.Homeland.Game.Elements.ElementRemovedEvent += OnRemoved;
                }
                else
                {
                    pad.Enabled = false;
                }
            }
        }
        
        private void OnRemoved(GameElement subject)
        {
            if (this.State == StateEnum.Deploying)
            {
                EnablePlayer();
            }
            else
            {
                _PlayOrder.Clear();
            }
        }
        
        void CheckCount()
        {
            bool test = false;
            
            PlayerPad playerPad1 = _LaunchingArea.PlayerPad1;
            PlayerPad playerPad2 = _LaunchingArea.PlayerPad2;
            
            bool loadedOrEmpty1 = (
                playerPad1.Homeland.State == Homeland.StateEnum.Full ||
                playerPad1.Homeland.State == Homeland.StateEnum.Empty);
            bool loadedOrEmpty2 = (
                playerPad2.Homeland.State == Homeland.StateEnum.Full ||
                playerPad2.Homeland.State == Homeland.StateEnum.Empty);
            if (loadedOrEmpty1 && loadedOrEmpty2)
            {
                test = true;
            }
            
            bool empty1 = (playerPad1.Homeland.State == Homeland.StateEnum.Empty);
            bool empty2 = (playerPad2.Homeland.State == Homeland.StateEnum.Empty);
            if (empty1 && empty2)
            {
                test = false;
            }
            
            _LaunchingArea.Deploying = test;
        }
        
        void Homeland1StateChanged(Homeland homland)
        {
            CheckCount();
        }
        
        void Homeland2StateChanged(Homeland homland)
        {
            CheckCount();
        }
        
        void PlayerPad1StateChanged(Homeland homland)
        {
            CheckCount();
        }
        
        void PlayerPad2StateChanged(Homeland homland)
        {
            CheckCount();
        }
        
        private void FireTick()
        {
            if (Step != null)
            {
                Step(this);
            }
        }
        
        
    }
}
